﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SIA.Configurators
{
    public interface IDictionaryProperty : IDictionary<String, IDictionaryProperty>
    {
        String PropertyValue { get; set; }
        String PropertyKey { get; set; }
        /// <summary>Riempe tutte proprietà</summary>
        void load();
        /// <summary>Unisce due IDictionaryProperty</summary>
        /// <param name="dProperty"></param>
        void Merge(IDictionaryProperty dProperty);
        /// <summary>Ritorna la propietà con la chiave specifica</summary>
        /// <param name="key"></param>
        /// <returns></returns>
        IDictionaryProperty Find(String key);
    }

    public abstract class AbstractDictionaryProperty : Dictionary<String, IDictionaryProperty>, IDictionaryProperty
    {
        protected String _propertyValue = "";
        protected String _propertyKey = "";

        public String PropertyValue { get { return _propertyValue; } set { _propertyValue = value; } }        
        public String PropertyKey { get { return _propertyKey; } set { _propertyKey = value; } }
        
        abstract public void load();

        new public IDictionaryProperty this[String key]
        {
            get
            {
                if (this.ContainsKey(key))
                    return base[key];
                if (this.ContainsKey(key.ToUpper()))
                    return base[key.ToUpper()];
                if (this.ContainsKey(key.ToLower()))
                    return base[key.ToLower()];
                else
                    return new SimpleDictionaryProperty(key, key + ": VOID");
            }
            set
            {
                if (this.ContainsKey(key))
                    base[key] = value;
                if (this.ContainsKey(key.ToUpper()))
                    base[key.ToUpper()] = value;
                else
                    base.Add(key, value);
            }
        }

        new public void Add(String key, IDictionaryProperty value)
        {
            if (key == "") return;
            if (key == null) return;

            if (value.PropertyValue == "") value.PropertyValue = key;
            if (this.ContainsKey(key))
                this[key] = value;
            else if (this.ContainsKey(key.ToUpper()))
                this[key.ToUpper()] = value;
            else
                base.Add(key.ToUpper(), value);
        }

        new public void Remove(String key)
        {
            if (this.ContainsKey(key)) base.Remove(key);
            if (this.ContainsKey(key.ToUpper())) base.Remove(key.ToUpper());
            if (this.ContainsKey(key.ToLower())) base.Remove(key.ToLower());
        }
       
        public override string ToString()
        {
            return PropertyValue;
        }

        public void Merge(IDictionaryProperty dProperty)
        {
            foreach (KeyValuePair<String, IDictionaryProperty> kp in dProperty)
                this.Add(kp.Key, kp.Value);
        }

        public IDictionaryProperty Find(String key)
        {
            if (this.PropertyKey == key) return this;
            if (this.ContainsKey(key))
                return this[key];
            if (this.ContainsKey(key.ToUpper()))
                return this[key];
            if (this.ContainsKey(key.ToLower()))
                return this[key];
            
            foreach (IDictionaryProperty dp in this.Values)
            {
                IDictionaryProperty fp = dp.Find(key);
                if (fp != null) return fp;
            }
            return null;
        }
    }

    public class SimpleDictionaryProperty : AbstractDictionaryProperty
    {
        public SimpleDictionaryProperty(String propertyKey, String propertyValue)
        {
            this._propertyKey = propertyKey;
            this._propertyValue = propertyValue;            
        }

        public override void load() { }
    }
}
